
#ifndef TCP_SERVER_H_
#define TCP_SERVER_H_


#include <functional>
#include <string>
#include <map>
#include <mutex>
#include "Socket.h"
#include <thread>
#include "Poller.h"
#include <fcntl.h>
#include "Connection.h"
#include "TimerHeap.h"

class TcpServer
{
private:
	//最多接入客户端的数量
	int					m_nMaxConnectNum;
	//epoll子线程数量
	int					m_nThreadsNum;
	//epoll子线程ID用到
	int					m_nPollerId;
	//监听线程运行状态, 退出用到
	bool 			m_bListenRuning;
	//worker子线程运行状态, 退出用到
	bool 			m_bSubRuning;
	//连接池对象
	CConnection  m_ListConn;
	//服务器监听socket
	Socket 			m_ListenSocket;

	//主线程listen线程对象
	std::thread  	m_threadListen;

	// 主线程Epoll对象
	Poller			m_EpollListen;

	//子线程
	std::thread* m_threadSub;

	// 子线程Epoll对象,动态初始化多个 
	Poller* m_EpollSub;
	//事件列表类型
	typedef std::vector<struct epoll_event> EventList;
private:
	//定时器ID
	static int			m_nTimer_ID;	

	//时间堆定时器
	TimerHeap	m_timerHeap;							
private:
	//设置非阻塞
	void						Setnonblocking(int fd);
	//定时器回调
	static void			TimerCallBack(void* user_data);
public:
	//构造
	TcpServer();
	//析构
	virtual  ~TcpServer();
	//启动TCP服务器	
	void   			  Start(int  nPort = 58888, int  nThreadWorker=2, int  nMax = 10000);
	//sblisten  noblock 
	void   			  InitListen(int nPort);
	//启动监听线程
	void 			  ThreadListenFunc();
	//处理客户端连接时间，EPOLL_IN,EPOLL_OUT,收发数据，关闭
	void 			  ThreadEpollSub();
	//终止运行
	void   			  Stop();
protected:	
	void 			  AcceptNewConnection();
	//新连接到来
	virtual void OnNewConnection(sClient* pConn) = 0;
	//有数据到来
	virtual void OnConnectionRead(sClient* pConn) = 0;
	//连接关闭
	virtual void OnConnectionClose(sClient* pConn) = 0;
	//连接超时
	virtual void OnConnectionTimeOut(sClient* pConn) = 0;
	//设置数据来时的读处理函数
	virtual void HandleRead(sClient* pConn);
	//可写触发
	virtual void HandleWrite(sClient* pConn) = 0;
	//设置数据发送时的写处理函数
protected:
	//处理关闭
	virtual void HandleClose(sClient* pConn);
public:
	//epoll操作函数
	void				AddEvent(sClient* p_Conn, int  nFd, uint32_t  eventType);
	void				RemoveEvent(sClient* p_Conn, int  nFd, uint32_t  eventType);
	void				UpdateEvent(sClient* p_Conn, int  nFd, uint32_t  eventType, int  nAdd);
	//是否是定时器关闭的，设备状态关闭状态是否已经被锁
	void				CloseConnection(sClient* pConn, bool bTimer = false, bool  bLock = false);
	//socket接收
	ssize_t		RecvFun(sClient* pConn, char* buff, ssize_t buflen);
};
#endif